package com.cloudkinto.service.order.impl;

import cn.afterturn.easypoi.excel.entity.ExportParams;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.assist.ISqlRunner;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cloudkinto.common.DicBusinessItemConstant;
import com.cloudkinto.common.constant.SysConstant;
import com.cloudkinto.common.error.ErrorEnum;
import com.cloudkinto.common.exception.BizException;
import com.cloudkinto.common.exception.NotSufficientFundsException;
import com.cloudkinto.common.utils.ExcelUtils;
import com.cloudkinto.common.utils.OkHttpUtils;
import com.cloudkinto.common.utils.StringsUtil;
import com.cloudkinto.common.utils.TimeUtils;
import com.cloudkinto.common.web.PageResult;
import com.cloudkinto.common.web.SingleResult;
import com.cloudkinto.dao.*;
import com.cloudkinto.entity.*;
import com.cloudkinto.service.finance.CompanyAccountService;
import com.cloudkinto.service.operate.OperateRecordService;
import com.cloudkinto.service.operate.vo.OperateRes;
import com.cloudkinto.service.order.OrderShopifyService;
import com.cloudkinto.service.order.vo.OrderFulfillmentOrderEntity;
import com.cloudkinto.service.order.vo.OrderShopifyLocationEntity;
import com.cloudkinto.service.order.vo.OrderTransactionEntity;
import com.cloudkinto.service.order.vo.ShopifyShippingEneity;
import com.cloudkinto.service.order.vo.amazon.AmazonOrderExcelExportVo;
import com.cloudkinto.service.order.vo.amazon.AmazonOrderItemExcelExportVo;
import com.cloudkinto.service.order.vo.amazon.OrderAmazonExcelReq;
import com.cloudkinto.service.order.vo.amazon.UpdateSysMemoReq;
import com.cloudkinto.service.order.vo.shopify.*;
import com.cloudkinto.service.orderoutput.OrderOutputService;
import com.cloudkinto.service.orderoutput.impl.OrderOutputServiceImpl;
import com.cloudkinto.service.orderoutput.vo.OrderOutputAddReq;
import com.cloudkinto.service.orderoutput.vo.OrderOutputPackageAddReq;
import com.cloudkinto.service.orderoutput.vo.OrderOutputProductAddReq;
import com.cloudkinto.service.region.JpRegionService;
import com.cloudkinto.service.shipprice.ShipPriceService;
import okhttp3.*;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * <p>
 * service实现类
 * </p>
 *
 * @author ding
 * @since 2021-09-23
 */
@Service
@Transactional(rollbackFor = Exception.class)//事务回滚
public class OrderShopifyServiceImpl extends ServiceImpl<OrderShopifyDao, OrderShopifyDo> implements OrderShopifyService {
    private static final String SHOPIFY_LOCATION = "shopify_location:";
    @Autowired
    private OrderShopifyDao dao;
    @Autowired
    private ShopDao shopDao;
    @Autowired
    private OrderShopifyProductDao productDao;
    @Autowired
    private OrderShopifyProductDao orderShopifyProductDao;
    @Autowired
    private UserDao userDao;
    @Autowired
    private ProductInfoDao productInfoDao;
    @Autowired
    private OperateRecordService operateRecordDao;
    @Autowired
    private JpRegionService mRegionService;
    @Autowired
    private StockRecordDao stockDao;
    @Autowired
    private StorageDao storageDao;
    @Autowired
    private ShipPriceService shipPriceService;
    @Autowired
    private ProductSkuMapDao productSkuMapDao;
    @Autowired
    private OrderOutputService outputService;
    @Autowired
    private CompanyAccountService companyAccountService;
    @Autowired
    private OrderOutputDao orderOutputDao;
    @Autowired
    private OrderOutputProductDao orderOutputProductDao;
    @Autowired
    private DicBusinessItemDao dicBusinessItemDao;
    @Autowired
    private OrderShopifyShipDao orderShopifyShipDao;

    @Autowired
    private OrderShopifyShippingLinesDao shippingLinesDao;
    @Autowired
    private RedisTemplate redisTemplate;

    private final Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    private OrderOutputPackageDetailDao packageDetailDao;

    @Override
    public SingleResult addInit() {
        return SingleResult.success("");
    }

    @Override
    public Object add(Object req, Long userId) {
        OrderShopifyDo entityDo = new OrderShopifyDo();
        BeanUtils.copyProperties(req, entityDo);
        handlerAddBefore(entityDo, userId);
        dao.insert(entityDo);
        return handlerAddAfter(entityDo);
    }

    //新增校验
    private void addCheck(Object req) {

    }

    //做新增之前要执行的业务定制处理
    private void handlerAddBefore(OrderShopifyDo entityDo, Long userId) {
//        entityDo.setCreateBy(userId);
//        entityDo.setCreateTime(new Date());
//        entityDo.setDeleteFlag(SysConstant.DELETE_FLAG_FALSE);
    }

    //将新增的do转换成要返回的实体
    private Object handlerAddAfter(OrderShopifyDo entityDo) {
        Object res = new Object();
        BeanUtils.copyProperties(entityDo, res);
        return res;
    }

    @Override
    public SingleResult updateInit(Long id) {
        return SingleResult.success("");
    }

    @Override
    public Object update(Object req, Long userId) {
        /*OrderShopifyDo entityDo = dao.selectById(req.getId());
        BeanUtils.copyProperties(req, entityDo);
        handlerUpdateBefore(entityDo, userId);
        dao.updateById(entityDo);
        return handlerUpdateAfter(entityDo);*/
        return null;
    }

    //编辑校验
    private void updateCheck(Object req) {

    }

    @Override
    public void sendOut(List<Long> orderOutputIds) {
        //发货的参数
        OrderShopifyFulfillmentAddEntity fulfillmentAddEntity = new OrderShopifyFulfillmentAddEntity();
        //根据orderOutputId获取 orderNo trackId trackNumber
        for (Long outPutId : orderOutputIds) {
            OrderOutputDo orderOutputDo = orderOutputDao.selectById(outPutId);
            if (orderOutputDo == null) {
                continue;
            }
            ShopDo shopDo = shopDao.selectById(orderOutputDo.getShopId());
            if (shopDo == null) {
                throw new BizException(SysConstant.Shop_NotExist);
            }
            fulfillmentAddEntity.setTracking_number(orderOutputDo.getTrackNumber());
            //根
            DicBusinessItemDo itemDo = dicBusinessItemDao.selectById(orderOutputDo.getTrackId());
            if (itemDo == null) {
                continue;
            }
            fulfillmentAddEntity.setTracking_company(itemDo.getDicItemValue());
            OrderShopifyDo orderShopifyDo = dao.selectOne(new LambdaQueryWrapper<OrderShopifyDo>().eq(OrderShopifyDo::getOrderNumber, orderOutputDo.getOrderNo()));
            if (orderShopifyDo == null) {
                continue;
            }
            Long orderId = orderShopifyDo.getOrderId();//url地址的oderid
            //根据order的id 获取 product （items）
            List<OrderShopifyProductDo> orderShopifyProductDoList = orderShopifyProductDao.selectList(new LambdaQueryWrapper<OrderShopifyProductDo>().eq(OrderShopifyProductDo::getOrderId, orderShopifyDo.getId()));
            List<OrderShopifyFulfillmentAddEntity.LineItem> line_items = new ArrayList<>();
            orderShopifyProductDoList.forEach(shopifyProductDo -> {
                OrderShopifyFulfillmentAddEntity.LineItem item = new OrderShopifyFulfillmentAddEntity.LineItem();
                item.setId(shopifyProductDo.getItemId());
                line_items.add(item);
            });
            fulfillmentAddEntity.setLine_items(line_items);
            System.out.println(JSONObject.toJSONString(fulfillmentAddEntity));
            String url = "https://" + shopDo.getShopifyHost() + "/admin/api/2021-07/orders/" + orderId + "fulfillments.json";
            String s = httpPost(url, shopDo, JSON.toJSONString(fulfillmentAddEntity));
            JSONObject jsonObject = JSON.parseObject(s);
            if (jsonObject.getJSONObject("fulfillment") != null) {
                //平台添加成功
                if (jsonObject.getJSONObject("fulfillment").getLong("id") != null) {
                    //更新为已发货
                    orderShopifyDo.setFulfillmentStatus("fulfilled");
                    dao.updateById(orderShopifyDo);
                    //t_order_shopify_ship 添加
                    orderShopifyProductDoList.forEach(shopifyProductDo -> {
                        OrderShopifyShipDo orderShopifyShipDo = new OrderShopifyShipDo();
                        orderShopifyShipDo.setOrderId(orderId);
                        orderShopifyShipDo.setShipmentStatus("fulfilled");
                        orderShopifyShipDo.setStatus("fulfilled");
                        orderShopifyShipDo.setTrackingCompany(fulfillmentAddEntity.getTracking_company());
                        orderShopifyShipDo.setTrackingNumber(fulfillmentAddEntity.getTracking_number());
                        orderShopifyShipDo.setUpdatedAt(new Date());
                        orderShopifyShipDao.insert(orderShopifyShipDo);
                    });
                }
            }
        }
    }

    @Override
    public SingleResult sync(Long shopId, String startDate, String endDate) {
        ShopDo shopDo = shopDao.selectById(shopId);
        long lastId = 0;
        if (shopDo == null) {
            throw new BizException(SysConstant.Shop_NotExist);
        }
//        int count = getOrderCount(shopDo, startDate, endDate);
        String url = "https://" + shopDo.getShopifyHost() + "/admin/api/2023-07/orders.json?status=any";
        Map<String, String> bodyMap = null;
        List<String> orderFiledIds = new ArrayList<>();
        do {
            if (bodyMap != null) {
                url = bodyMap.get("page");
            }
            bodyMap = httpGet(url, shopDo, startDate, endDate);
            JSONArray jsonArray = JSONObject.parseObject(bodyMap.get("body")).getJSONArray("orders");
            List<OrderShopifyEntity> orderShopifyEntities = JSON.parseArray(jsonArray.toJSONString(), OrderShopifyEntity.class);
            orderFiledIds.addAll(handlerSyncAfter(orderShopifyEntities, shopDo));
        } while (bodyMap != null && StringUtils.isNotBlank(bodyMap.get("page")));
        String[] stringIds = new String[]{};
        orderFiledIds.toArray(stringIds);
//        sendOut(stringIds, 338L, shopDo.getCompanyId(), shopDo.getAutoSendOutFlag());

        return SingleResult.success();
    }

    private Map httpGet(String url, ShopDo shopDo, String startDate, String endDate) {
        Map<String, String> map = new HashMap();
        OkHttpClient.Builder client = OkHttpUtils.getUnsafeOkHttpClient().newBuilder();
        client.connectTimeout(60, TimeUnit.SECONDS).readTimeout(60, TimeUnit.SECONDS).writeTimeout(60, TimeUnit.SECONDS).retryOnConnectionFailure(true);
        Map<String, String> params = new HashMap<>();
        if (!url.contains("page_info")) {
            String parseStartDate = "";
            String parseEndDate = "";
            //传格林威治时区时间
            if (startDate != null) {
                parseStartDate = TimeUtils.formatDate(TimeUtils.parseDate(startDate, "yyyy-MM-dd"), "yyyy-MM-dd'T'HH:mm:ss", "GMT");
                url = url + "&created_at_min=" + parseStartDate;
            }
            if (endDate != null) {
                parseEndDate = TimeUtils.formatDate(TimeUtils.parseDate(endDate, "yyyy-MM-dd"), "yyyy-MM-dd'T'HH:mm:ss", "GMT");
                url = url + "&created_at_max=" + parseEndDate;
            }
            url = url + "&limit=" + 200;
        }
        Request request = new Request.Builder().addHeader("Content-Type", "application/json;charset=utf-8")
                .addHeader("X-Shopify-Access-Token", shopDo.getShopifyToken())
                .url(url)
                .get()
                .build();
        Response response = null;
        String body = "";
        try {
            response = client.build().newCall(request).execute();
            body = response.body().string();
            System.out.println(body);
            map.put("body", body);
            map.put("page", getNextpage(response.header("Link")));
            return map;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }


    private String httpGet(String url, ShopDo shopDo) {
        Map<String, String> map = new HashMap();
        OkHttpClient.Builder client = OkHttpUtils.getUnsafeOkHttpClient().newBuilder();
        client.connectTimeout(60, TimeUnit.SECONDS).readTimeout(60, TimeUnit.SECONDS).writeTimeout(60, TimeUnit.SECONDS).retryOnConnectionFailure(true);
        Map<String, String> params = new HashMap<>();
        Request request = new Request.Builder().addHeader("Content-Type", "application/json;charset=utf-8").addHeader("X-Shopify-Access-Token", shopDo.getShopifyToken()).url(url).get().build();
        Response response = null;
        String body = "";
        try {
            response = client.build().newCall(request).execute();
            body = response.body().string();
            System.out.println(body);
            return body;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private String getNextpage(String link) {
        if (StringUtils.isBlank(link)) return link;
        String[] strings = link.replaceAll("<", "").replaceAll(">", "").split(",");
        for (String string : strings) {
            String[] split = string.split(";");
            String url = split[0];
            String type = split[1];
            if (type.contains("next")) {
                return url;
            }
        }
        return null;
    }


    @Override
    public void test() {
        ShopDo shopDo = shopDao.selectById(6);

        List<OrderFulfillmentOrderEntity> fulfillmentOrders = this.getFulfillmentOrders(shopDo, 4920922538037L);//4920922538037  4889843793968L
        System.out.println(fulfillmentOrders);


//        String url1 = "https://" + shopDo.getShopifyHost() + "/admin/api/2023-07/fulfillment_orders/5921151451184/reschedule.json";  5751389192245
//        //{"errors":["Fulfillment order must be scheduled."]}
//        JSONObject newFull = new JSONObject();
//        newFull.put("new_fulfill_at", "2024-07-8 18:30 UTC");
//        JSONObject full = new JSONObject();
//        full.put("fulfillment_order", newFull);
//        String s1 = httpPost(url1, shopDo, full.toJSONString());
//        JSONObject jsonObject1 = JSON.parseObject(s1);
//        System.out.println(jsonObject1);
//
//        //admin/api/2023-07/fulfillment_orders/1046000819/open. json
//        String url = "https://" + shopDo.getShopifyHost() + "/admin/api/2023-07/fulfillment_orders/5921151451184/open.json";
//        //{"errors":["Expected fulfillment order status to be scheduled but it was closed."]}
//        String s = httpPost(url, shopDo, "");
//        JSONObject jsonObject = JSON.parseObject(s);
//        System.out.println(jsonObject);

    }

    private String httpPost(String url, ShopDo shopDo, String requestBody) {
        OkHttpClient.Builder client = OkHttpUtils.getUnsafeOkHttpClient().newBuilder();
        client.connectTimeout(60, TimeUnit.SECONDS).readTimeout(60, TimeUnit.SECONDS).writeTimeout(60, TimeUnit.SECONDS).retryOnConnectionFailure(true);
        Request request = new Request.Builder().addHeader("Content-Type", "application/json;charset=utf-8").addHeader("X-Shopify-Access-Token", shopDo.getShopifyToken()).url(url).post(RequestBody.create(MediaType.get("application/json"), requestBody)).build();
        Response response = null;
        String body = "";
        try {
            response = client.build().newCall(request).execute();
            body = response.body().string();
            System.out.println(body);
            return body;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    private String httpPut(String url, ShopDo shopDo, String requestBody) {
        OkHttpClient.Builder client = OkHttpUtils.getUnsafeOkHttpClient().newBuilder();
        client.connectTimeout(60, TimeUnit.SECONDS).readTimeout(60, TimeUnit.SECONDS).writeTimeout(60, TimeUnit.SECONDS).retryOnConnectionFailure(true);
        Request request = new Request.Builder().addHeader("Content-Type", "application/json;charset=utf-8").addHeader("X-Shopify-Access-Token", shopDo.getShopifyToken()).url(url).put(RequestBody.create(MediaType.get("application/json"), requestBody)).build();
        Response response = null;
        String body = "";
        try {
            response = client.build().newCall(request).execute();
            body = response.body().string();
            System.out.println(body);
            return body;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }


    private List<String> handlerSyncAfter(List<OrderShopifyEntity> orderShopifyEntities, ShopDo shopDo) {
        List<String> insertIds = new ArrayList<>();
        orderShopifyEntities.stream().forEach(orderShopifyEntity -> {
            try {
                LambdaQueryWrapper<OrderShopifyDo> orderShopifyDoWrapper = new LambdaQueryWrapper<>();
                orderShopifyDoWrapper.eq(OrderShopifyDo::getOrderId, orderShopifyEntity.getId());
                OrderShopifyDo shopifyDo = dao.selectOne(orderShopifyDoWrapper);
                if (shopifyDo == null) shopifyDo = new OrderShopifyDo();
                if (shopDo == null) {
                    shopifyDo.setCompanyId(1L);
                    shopifyDo.setShopId(33L);
                } else {
                    shopifyDo.setCompanyId(shopDo.getCompanyId());
                    shopifyDo.setShopId(shopDo.getId());
                }
                shopifyDo.setOrderNumber(orderShopifyEntity.getOrder_number());
                shopifyDo.setOrderName(orderShopifyEntity.getName());
                if (orderShopifyEntity.getGateway() != null) {
                    shopifyDo.setPaymentGatewayNames(orderShopifyEntity.getGateway());
                } else if (orderShopifyEntity.getPayment_gateway_names() != null && orderShopifyEntity.getPayment_gateway_names().size() > 0) {
                    String payments = orderShopifyEntity.getPayment_gateway_names().stream().collect(Collectors.joining(","));
                    shopifyDo.setPaymentGatewayNames(payments);
                }
                shopifyDo.setOrderId(orderShopifyEntity.getId());
                shopifyDo.setTotalPrice(orderShopifyEntity.getTotal_price());
                shopifyDo.setSubtotalPrice(orderShopifyEntity.getSubtotal_price());
                shopifyDo.setReference(orderShopifyEntity.getReference());
                shopifyDo.setNumber(orderShopifyEntity.getNumber());
                shopifyDo.setTotalTax(orderShopifyEntity.getTotal_tax());
                shopifyDo.setTotalDiscounts(orderShopifyEntity.getTotal_discounts());
                shopifyDo.setPhone(orderShopifyEntity.getPhone());
                if (orderShopifyEntity.getShipping_address() != null) {
                    shopifyDo.setShippingAddress(orderShopifyEntity.getShipping_address().getAddress1() + orderShopifyEntity.getShipping_address().getAddress2());
                    shopifyDo.setShippingZip(orderShopifyEntity.getShipping_address().getZip());
                    shopifyDo.setShippingProvince(StringsUtil.getJpAreaByEnglishCode(orderShopifyEntity.getShipping_address().getProvince()));
                    shopifyDo.setShippingCity(orderShopifyEntity.getShipping_address().getCity());
                    shopifyDo.setShippingPhone(orderShopifyEntity.getShipping_address().getPhone());
                    shopifyDo.setShippingName(orderShopifyEntity.getShipping_address().getLast_name() + " " + orderShopifyEntity.getShipping_address().getFirst_name());
                }
                if (orderShopifyEntity.getLocation_id() != 0)
                    shopifyDo.setLocationId(orderShopifyEntity.getLocation_id());
                shopifyDo.setCreatedAt(orderShopifyEntity.getCreated_at());
                shopifyDo.setUpdatedAt(orderShopifyEntity.getUpdated_at());
                shopifyDo.setProcessedAt(orderShopifyEntity.getProcessed_at());
//            shopifyDo.setTaxesIncluded(orderShopifyEntity.getTotal_tax());
//            shopifyDo.setConfirmed(orderShopifyEntity.getClient_details());
                shopifyDo.setContactEmail(orderShopifyEntity.getContact_email());
                shopifyDo.setEmail(orderShopifyEntity.getEmail());
                shopifyDo.setCurrency(orderShopifyEntity.getCurrency());
                if (orderShopifyEntity.getFulfillment_status() == null) {
                    shopifyDo.setFulfillmentStatus("unshipped");
                } else {
                    shopifyDo.setFulfillmentStatus(orderShopifyEntity.getFulfillment_status());
                }
                shopifyDo.setFinancialStatus(orderShopifyEntity.getFinancial_status());
                if (shopifyDo.getId() == null || shopifyDo.getId() == 0) {
                    shopifyDo.setIsSendOut(0);
                    shopifyDo.setIsUploadExpress(0);
                    save(shopifyDo);
                    insertIds.add(shopDo.getId() + "");
                } else {
                    updateById(shopifyDo);
                }
                for (OrderShopifyEntity.Line_itemsEntity line_item : orderShopifyEntity.getLine_items()) {
                    LambdaQueryWrapper<OrderShopifyProductDo> itemWrapper = new LambdaQueryWrapper<>();
                    itemWrapper.eq(OrderShopifyProductDo::getItemId, line_item.getId());
                    OrderShopifyProductDo productDo = productDao.selectOne(itemWrapper);
                    if (productDo == null) productDo = new OrderShopifyProductDo();
                    productDo.setFulfillableQuantity(line_item.getFulfillable_quantity());
                    productDo.setQuantity(line_item.getQuantity());
                    productDo.setVariantTitle(line_item.getVariant_title());
                    productDo.setTitle(line_item.getTitle());
                    productDo.setPrice(line_item.getPrice());
                    productDo.setProductId(line_item.getProduct_id());
                    productDo.setItemId(line_item.getId());
                    productDo.setSku(line_item.getSku());
                    productDo.setSkuName(line_item.getName());
                    productDo.setOrderId(shopifyDo.getId());
                    if (productDo.getId() == null || productDo.getId() == 0) {
                        productDao.insert(productDo);
                    } else {
                        productDao.updateById(productDo);
                    }
                }
                for (OrderShopifyShippingEntity shopifyShippingEntity : orderShopifyEntity.getShipping_lines()) {
                    OrderShopifyShippingLinesDo productDo = shippingLinesDao.selectById(shopifyShippingEntity.getId());
                    if (productDo == null || productDo.getId() == null || productDo.getId() == 0) {
                        productDo = new OrderShopifyShippingLinesDo();
                        BeanUtils.copyProperties(shopifyShippingEntity, productDo);
                        try {
                            productDo.setPrice(Double.parseDouble(shopifyShippingEntity.getPrice()));
                            productDo.setDiscountedPrice(Double.parseDouble(shopifyShippingEntity.getDiscountedPrice()));
                        } catch (NumberFormatException e) {
                            e.printStackTrace();
                            logger.error("=============================" + orderShopifyEntity.getOrder_number() + "OrderShopifyShippingLinesDo出错price设置");
                        }
                        productDo.setOrderId(shopifyDo.getId());
                        shippingLinesDao.insert(productDo);
                    } else {
                        BeanUtils.copyProperties(shopifyShippingEntity, productDo);
                        productDo.setOrderId(shopifyDo.getId());
                        shippingLinesDao.updateById(productDo);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                logger.error("=============================" + orderShopifyEntity.getOrder_number() + "订单出错");
                logger.error(e.getLocalizedMessage());
            }
        });
        return insertIds;
    }

    //做修改之前要执行的业务定制处理
    private void handlerUpdateBefore(OrderShopifyDo entityDo, Long userId) {
//        entityDo.setUpdateBy(userId);
//        entityDo.setUpdateTime(new Date());
    }

    //做修改之后要执行的业务定制处理
    private Object handlerUpdateAfter(OrderShopifyDo entityDo) {
        Object res = new Object();
        BeanUtils.copyProperties(entityDo, res);
        return res;
    }

    @Override
    public int delete(Long id, Long userId) {
        OrderShopifyDo entityDo = dao.selectById(id);
        handlerDeleteBefore(entityDo, userId);
        return dao.deleteById(id);
    }

    //做删除之前要执行的业务定制处理
    private void handlerDeleteBefore(OrderShopifyDo entityDo, Long userId) {
//        entityDo.setDeleteBy(userId);
//        entityDo.setDeleteTime(new Date());
    }

    @Override
    public OrderShopifyRes detail(Long id) {
        OrderShopifyDo entityDo = dao.selectById(id);
        OrderShopifyDetaillRes res = new OrderShopifyDetaillRes();
        BeanUtils.copyProperties(entityDo, res);
        return handlerDetailAfter(res);
    }

    //查询明细之后要执行的业务定制处理
    private OrderShopifyDetaillRes handlerDetailAfter(OrderShopifyDetaillRes res) {
        ShopDo shopDo = shopDao.selectById(res.getShopId());
        res.setFulfillmentStatus(getOrderShipTypeStr(res.getFulfillmentStatus()));
        res.setFinancialStatus(getOrderStatusStr(res.getFinancialStatus()));
        if (shopDo != null) res.setShopName(shopDo.getShopName());
        List<OrderShopifyProductDo> shopifyProductDos = orderShopifyProductDao.selectList(new LambdaQueryWrapper<OrderShopifyProductDo>().eq(OrderShopifyProductDo::getOrderId, res.getId()));
        if (shopifyProductDos.size() > 0) {
            List<String> skuList = shopifyProductDos.stream().map(OrderShopifyProductDo::getSku).collect(Collectors.toList());
            String sku = StringUtils.join(skuList, ",");
            res.setSku(sku);
        }
        List<OrderShopifyItemRes> orderShopifyItemResList = new ArrayList<>();
        shopifyProductDos.forEach(orderShopifyProductDo -> {
            OrderShopifyItemRes itemRes = new OrderShopifyItemRes();
            BeanUtils.copyProperties(orderShopifyProductDo, itemRes);
            orderShopifyItemResList.add(itemRes);
        });

        //查询日志
        List<OperateRes> operateResList = operateRecordDao.getOperateList(res.getId(), 7);
        res.setOperateResList(operateResList);
        res.setItemResList(orderShopifyItemResList);
        return res;
    }

    @Override
    public void exportExcel(Map<String, String> map, OrderAmazonExcelReq req, HttpServletResponse response) throws Exception {
        List<OrderShopifyDo> OrderShopifyDoList = null;

        if (CollectionUtils.isEmpty(req.getIds())) {
            QueryWrapper<OrderShopifyDo> wrapper = queryBuild(map);
            OrderShopifyDoList = this.baseMapper.selectList(wrapper);
        } else {
            LambdaQueryWrapper<OrderShopifyDo> wrapper = new LambdaQueryWrapper<>();
            wrapper.in(OrderShopifyDo::getId, req.getIds()).eq(OrderShopifyDo::getCompanyId, map.get("companyId")).orderByDesc(OrderShopifyDo::getCreatedAt);
            OrderShopifyDoList = this.baseMapper.selectList(wrapper);
        }
        if (OrderShopifyDoList.size() > 5000) {
            response.sendError(500, "数据超过1000条，请分日期导出");
            throw new BizException(SysConstant.File_Export_ToMuch, 1000);
        }
        List<OrderShopifyResExcelExportVo> excelExportVoList = new ArrayList<>();

        if (!CollectionUtils.isEmpty(OrderShopifyDoList)) {
            LambdaQueryWrapper<OrderShopifyProductDo> itemsWrapper;
            for (OrderShopifyDo OrderShopifyDo : OrderShopifyDoList) {
                OrderShopifyResExcelExportVo excelExportVo = new OrderShopifyResExcelExportVo();
                BeanUtils.copyProperties(OrderShopifyDo, excelExportVo);

                itemsWrapper = new LambdaQueryWrapper<>();
                itemsWrapper.eq(OrderShopifyProductDo::getOrderId, OrderShopifyDo.getId());
                List<OrderShopifyProductDo> itemsDoList = productDao.selectList(itemsWrapper);

                List<AmazonOrderItemExcelExportVo> itemExcelExportVoList = new ArrayList<>();
                if (!CollectionUtils.isEmpty(itemsDoList)) {
                    for (OrderShopifyProductDo itemsDo : itemsDoList) {
                        AmazonOrderItemExcelExportVo itemExcelExportVo = new AmazonOrderItemExcelExportVo();
                        BeanUtils.copyProperties(itemsDo, itemExcelExportVo);
                        itemExcelExportVoList.add(itemExcelExportVo);
                    }
                }

//                excelExportVo.setItemExcelExportVoList(itemExcelExportVoList);

                excelExportVoList.add(excelExportVo);
            }
        }
        ExcelUtils.exportExcel(excelExportVoList, AmazonOrderExcelExportVo.class, "shopify订单", new ExportParams(), response);
    }

    @Override
    public SingleResult markSendOut(List<Long> ids, Long userId) {
        if (CollectionUtils.isEmpty(ids)) {
            throw new BizException(SysConstant.Pls_Choose_Order);
        }
        for (Long id : ids) {
            OrderShopifyDo OrderShopifyDo = this.baseMapper.selectById(id);
            if (OrderShopifyDo.getIsSendOut() == 0) {
                OrderShopifyDo.setIsSendOut(1);
                this.baseMapper.updateById(OrderShopifyDo);
                operateRecordDao.operateAddRecord(SysConstant.OPERATE_CLICK_SEND, OrderShopifyDo.getId(), userId, 7);

            }
        }
        return SingleResult.success();
    }
//
//    private void operateRecord(String str, OrderShopifyDo OrderShopifyDo, Long userId) {
//        OperateRecordDo operateRecordDo = new OperateRecordDo();
//        operateRecordDo.setContent(str);
//        operateRecordDo.setOperateTime(new Date());
//        operateRecordDo.setOperateBy(userId);
//        operateRecordDo.setType(7);
//        operateRecordDo.setThirdId(OrderShopifyDo.getId());
//        operateRecordDo.setDeleteFlag(0);
//        operateRecordDao.insert(operateRecordDo);
//    }

    @Override
    public SingleResult updateSysMemo(UpdateSysMemoReq req, Long userId, Long companyId) {
        OrderShopifyDo OrderShopifyDo = this.baseMapper.selectById(req.getId());
        OrderShopifyDo.setSystemMemo(req.getSystemMemo());
        this.baseMapper.updateById(OrderShopifyDo);
        return SingleResult.success("编辑成功", null);
    }

    @Override
    public SingleResult systemMemoInit(Long id) {
        OrderShopifyDo OrderShopifyDo = this.baseMapper.selectById(id);
        return SingleResult.success(OrderShopifyDo.getSystemMemo());
    }

    @Override
    public SingleResult sendOut(String[] ids, Long userId, Long companyId, boolean isAuto) {
//        sufficientFundsCheck(companyId);
        List<OrderOutputAddReq> orderOutputAddReqList = new ArrayList<>();
        List<String> failOrders = new ArrayList<>();
        if (ids == null || ids.length < 1) return SingleResult.failure("无数据");
        List<OrderShopifyDo> orderShopifyDos = this.baseMapper.selectBatchIds(Arrays.asList(ids));
        for (OrderShopifyDo OrderShopifyDo : orderShopifyDos) {
            if ("Canceled".equals(OrderShopifyDo.getFinancialStatus()) || "refunded".equals(OrderShopifyDo.getFinancialStatus()) || "voided".equals(OrderShopifyDo.getFinancialStatus())) {
                failOrders.add(StringsUtil.createI18Message("该订单已废弃") + OrderShopifyDo.getOrderName());
                continue;
            }
            if (!OrderShopifyDo.getFulfillmentStatus().equals("unshipped") && isAuto) {
                failOrders.add(StringsUtil.createI18Message("该订单不处于待发货状态") + OrderShopifyDo.getOrderName());
                continue;
            }
            OrderOutputAddReq res = new OrderOutputAddReq();
            LambdaQueryWrapper<OrderShopifyProductDo> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(OrderShopifyProductDo::getOrderId, OrderShopifyDo.getId());
            List<OrderShopifyProductDo> itemsDoList = productDao.selectList(wrapper);
            LambdaQueryWrapper<OrderShopifyShippingLinesDo> wrapperShippingLines = new LambdaQueryWrapper<>();
            wrapperShippingLines.eq(OrderShopifyShippingLinesDo::getOrderId, OrderShopifyDo.getId());
            List<OrderShopifyShippingLinesDo> shippingLinesDos = shippingLinesDao.selectList(wrapperShippingLines);
            if (shippingLinesDos != null && shippingLinesDos.size() > 0)
                for (OrderShopifyShippingLinesDo shippingLinesDo : shippingLinesDos) {
                    if (shippingLinesDo.getCode() != null) {
                        if (shippingLinesDo.getCode().contains("お急ぎ便")) {
                            res.setShipmentType(1);
                            break;
                        }
                    }
                }
            //订单
//            res.setOrderType(1);
//        res.setStatus(0);
            if ((StringUtils.isNotBlank(OrderShopifyDo.getPaymentGatewayNames()) && OrderShopifyDo.getPaymentGatewayNames().contains("代金引換"))
                    || (StringUtils.isNotBlank(OrderShopifyDo.getPaymentGatewayNames()) && OrderShopifyDo.getPaymentGatewayNames().contains("代金引换"))
                    || (StringUtils.isNotBlank(OrderShopifyDo.getPaymentGatewayNames()) && OrderShopifyDo.getPaymentGatewayNames().contains("Cash on Delivery (COD)"))) {
                res.setCod((int) OrderShopifyDo.getSubtotalPrice());
            } else if ((!OrderShopifyDo.getFinancialStatus().equals("authorized") && !OrderShopifyDo.getFinancialStatus().equals("paid"))) {
                failOrders.add(StringsUtil.createI18Message("该订单未付款") + OrderShopifyDo.getOrderName());
                continue;
            }
            res.setSendDate(new Date());
            res.setPlatformNumber("shopify");
            res.setPlatformNumber(OrderShopifyDo.getId() + "");
            res.setShopId(OrderShopifyDo.getShopId());
            res.setCompanyId(OrderShopifyDo.getCompanyId());
            res.setOrderNo(OrderOutputServiceImpl.SHOPIFY_PREFIX + OrderShopifyDo.getOrderNumber());
            res.setReceiverName(OrderShopifyDo.getShippingName());
            res.setTelPhone(OrderShopifyDo.getShippingPhone());
            res.setPostCode(OrderShopifyDo.getShippingZip());
            res.setArea(OrderShopifyDo.getShippingProvince());
            if (StringUtils.isNotBlank(OrderShopifyDo.getShippingCity())) {
                res.setAddress(OrderShopifyDo.getShippingCity() + OrderShopifyDo.getShippingAddress());
            } else {
                res.setAddress(OrderShopifyDo.getShippingAddress());
            }
//            if (OrderShopifyDo.getLastDeliveryDate() != null && OrderShopifyDo.getEarliestDeliveryDate() != null &&
//                    "Scheduled".equals(OrderShopifyDo.getShipmentServiceLevelCategory())) {
//                res.setDeliveryDate(TimeUtils.formatDate(OrderShopifyDo.getLastDeliveryDate()));
//                int time1 = Integer.parseInt(TimeUtils.formatDate(OrderShopifyDo.getEarliestDeliveryDate(), "HH")) + 1;
//                String startTime = time1 < 10 ? "0" + time1 : String.valueOf(time1);
//                int time2 = Integer.parseInt(TimeUtils.formatDate(OrderShopifyDo.getLastDeliveryDate(), "HH")) + 1;
//                String endTime = time2 < 10 ? "0" + time2 : String.valueOf(time2);
//                res.setDeliveryTime(startTime +
//                        "-" + endTime);
//            }
            long storageId = 0L;
            long stateId = 0;
            //item
            List<OrderOutputProductAddReq> orderOutputProductDetailList = new ArrayList<>();
            List<OrderShopifyProductDo> failedItems = new ArrayList<>();
            if (!CollectionUtils.isEmpty(itemsDoList)) {
                double[] size = new double[4];
                double shipPirce = 99999D;
                //默认仓库先捆包
                for (OrderShopifyProductDo itemsDo : itemsDoList) {
                    Long productId = getProductId(itemsDo.getSku(), OrderShopifyDo.getCompanyId());
                    if (productId == null) {
                        failOrders.add(StringsUtil.createI18Message(SysConstant.OrderYahoo_Product_Notfound, OrderShopifyDo.getOrderNumber(), itemsDo.getSku()));
                        continue;
                    }
                    stateId = mRegionService.getStateIdByPostCode(OrderShopifyDo.getShippingZip());
                    if (stateId <= 8) {//大阪地区优先发货仓库
                        storageId = 12L;
                    } else {//东京仓库优先发货仓库
                        storageId = 10L;
                    }
                    LambdaQueryWrapper<StockRecordDo> wrapper1 = new LambdaQueryWrapper<>();
                    wrapper1.eq(StockRecordDo::getShopId, res.getShopId()).eq(StockRecordDo::getProductInfoId, productId).eq(StockRecordDo::getStorageId, storageId);
                    StockRecordDo stockRecordDo = stockDao.selectOne(wrapper1);
                    if (stockRecordDo == null) {
                        failedItems.add(itemsDo);
                        continue;
                    }
                    int noDeliveredCount = stockDao.getOrderOutCount(productId, res.getShopId(), storageId) + stockDao.getOrderOutTurn2FbaCount(productId, res.getShopId(), storageId);
                    int count = itemsDo.getQuantity();
                    if (count < 1) count = itemsDo.getQuantity();
                    if (stockRecordDo.getCanSellCount() - noDeliveredCount < count) {//优先仓库有库存，优先仓库发货
                        failedItems.add(itemsDo);
                        continue;
                    }
                    OrderOutputProductAddReq productDetail = new OrderOutputProductAddReq();
                    productDetail.setOrderId(itemsDo.getOrderId());
                    productDetail.setProductId(productId);
                    productDetail.setCount(count);
                    orderOutputProductDetailList.add(productDetail);
                }
                OrderOutputPackageAddReq packageDetail = new OrderOutputPackageAddReq();
                List<OrderOutputPackageAddReq> packageAddReqList = new ArrayList<>();
                packageDetail.setProductList(orderOutputProductDetailList);
                OrderOutputAddReq addReq = new OrderOutputAddReq();
                BeanUtils.copyProperties(res, addReq);
                packageAddReqList.add(packageDetail);
                addReq.setStorageId(storageId);
                addReq.setPackageList(packageAddReqList);
                //默认仓库库存不足
                if (failedItems.size() != itemsDoList.size() && storageId != 0) {
                    orderOutputAddReqList.add(addReq);
                } //一个仓库是否发完所有订单
                if (failedItems.size() > 0) {
                    List<OrderOutputProductAddReq> productAddList = new ArrayList<>();
                    //剩余一件商品无库存
                    if (failedItems.size() == 1 && failedItems.get(0).getQuantity() == 1) {
                        storageId = 0L;
                        Long productId = getProductId(failedItems.get(0).getSku(), res.getCompanyId());
                        List<StorageDo> storageDos = storageDao.selectList(null);
                        int count = failedItems.get(0).getQuantity();
                        if (count < 1) count = failedItems.get(0).getQuantity();
                        for (StorageDo storageDo : storageDos) {//遍历仓库是否都有库存
                            LambdaQueryWrapper<StockRecordDo> wrapper2 = new LambdaQueryWrapper();
                            wrapper2.eq(StockRecordDo::getShopId, res.getShopId()).eq(StockRecordDo::getProductInfoId, productId).eq(StockRecordDo::getStorageId, storageDo.getId());
                            StockRecordDo stockRecordDo1 = stockDao.selectOne(wrapper2);
                            size = shipPriceService.countSameSkuSize(new double[4], productId, count);
                            int noDeliveredCount1 = stockDao.getOrderOutCount(productId, res.getShopId(), storageDo.getId()) + stockDao.getOrderOutTurn2FbaCount(productId, res.getShopId(), storageDo.getId());
                            if (stockRecordDo1 != null && stockRecordDo1.getCanSellCount() - noDeliveredCount1 >= count) {
                                List<ShipPriceDo> shipPriceDos = shipPriceService.queryByRegionAndSize(res.getPostCode(), size[3], size[0] + size[1] + size[2], size[0], size[1], size[2], res.getCod(), res.getShipmentType(), storageDo.getId(), 1);
                                if (shipPriceDos.size() < 1 || shipPriceDos.get(0).getPrice() == 0) continue;
                                if (shipPirce > shipPriceDos.get(0).getPrice()) {//选择最便宜的价格
                                    shipPirce = shipPriceDos.get(0).getPrice();
                                    storageId = storageDo.getId();
                                }
                            }
                        }
                        OrderOutputProductAddReq productDetail = new OrderOutputProductAddReq();
                        productDetail.setProductId(productId);
                        productDetail.setCount(count);
                        productAddList.add(productDetail);
                        OrderOutputPackageAddReq packageDetail1 = new OrderOutputPackageAddReq();
                        if (storageId != 0) {
                            List<OrderOutputPackageAddReq> packageAddReqList1 = new ArrayList<>();
                            packageDetail1.setProductList(productAddList);
                            OrderOutputAddReq addReq1 = new OrderOutputAddReq();
                            BeanUtils.copyProperties(res, addReq1);
                            packageAddReqList1.add(packageDetail1);
                            addReq1.setStorageId(storageId);
                            addReq1.setPackageList(packageAddReqList1);
//                            if (orderCount > 0) addReq.setOrderNo(addReq.getOrderNo() + "-" + orderCount);
//                            orderCount++;
                            orderOutputAddReqList.add(addReq1);
                        } else {
                            failOrders.add(StringsUtil.createI18Message(SysConstant.OrderYahoo_Stock_NotEnough, OrderShopifyDo.getOrderNumber(), failedItems.get(0).getSku()));
                        }
                    } else {
                        List<OrderOutputProductAddReq> productAddList1 = new ArrayList<>();
                        //多件商品无库存，第二优先捆包
                        List<OrderShopifyProductDo> productDoListFailed = new ArrayList<>();
                        List<OrderShopifyProductDo> productDoListSuccess = new ArrayList<>();
                        LambdaQueryWrapper<StorageDo> lambdaQueryWrapper = new LambdaQueryWrapper();
                        lambdaQueryWrapper.eq(StorageDo::getSupportShip, 1).ne(StorageDo::getId, storageId);
                        if (stateId <= 7) {
                            lambdaQueryWrapper.orderByDesc(StorageDo::getStorageArea);
                        } else {
                            lambdaQueryWrapper.orderByAsc(StorageDo::getStorageArea);
                        }
                        List<StorageDo> storageDos = storageDao.selectList(lambdaQueryWrapper);
                        storageId = 0L;
                        if (storageDos != null) {
                            kk:
                            for (StorageDo storageDo : storageDos) {
                                ;//遍历支持捆包仓库是否都有库存
                                for (OrderShopifyProductDo productDo : failedItems) {
                                    Long productId = getProductId(productDo.getSku(), res.getCompanyId());
                                    int count = productDo.getQuantity();
                                    if (count < 1) count = productDo.getQuantity();
                                    LambdaQueryWrapper<StockRecordDo> wrapper1 = new LambdaQueryWrapper();
                                    wrapper1.eq(StockRecordDo::getShopId, res.getShopId()).eq(StockRecordDo::getProductInfoId, productId).eq(StockRecordDo::getStorageId, storageDo.getId());
                                    StockRecordDo stockRecordDo = stockDao.selectOne(wrapper1);
                                    if (stockRecordDo == null) {
                                        productDoListSuccess.clear();
                                        productDoListFailed.clear();
                                        productDoListFailed.addAll(failedItems);
                                        continue kk;
                                    }
                                    int noDeliveredCount = stockDao.getOrderOutCount(productId, res.getShopId(), storageDo.getId()) + stockDao.getOrderOutTurn2FbaCount(productId, res.getShopId(), storageDo.getId());
                                    if (stockRecordDo.getCanSellCount() - noDeliveredCount < count) {
                                        productDoListSuccess.clear();
                                        productDoListFailed.clear();
                                        productDoListFailed.addAll(failedItems);
                                        continue kk;
                                    } else {
                                        productDoListSuccess.add(productDo);
                                    }
                                    storageId = storageDo.getId();
                                    OrderOutputProductAddReq productDetail = new OrderOutputProductAddReq();
                                    productDetail.setProductId(productId);
                                    productDetail.setCount(count);
                                    productAddList1.add(productDetail);
                                }
                                if (productDoListSuccess.size() == failedItems.size()) {
                                    productDoListSuccess.clear();
                                    productDoListFailed.clear();
                                    packageDetail = new OrderOutputPackageAddReq();
                                    List<OrderOutputPackageAddReq> packageAddReqList1 = new ArrayList<>();
                                    packageDetail.setProductList(productAddList1);
                                    OrderOutputAddReq addReq1 = new OrderOutputAddReq();
                                    BeanUtils.copyProperties(res, addReq1);
                                    packageAddReqList1.add(packageDetail);
                                    if (storageId != 0) {
                                        addReq1.setStorageId(storageId);
                                        addReq1.setPackageList(packageAddReqList1);
                                        orderOutputAddReqList.add(addReq1);
                                        break kk;
                                    }
                                } else {
                                    productDoListSuccess.clear();
                                    productDoListFailed.addAll(failedItems);
                                    continue kk;
                                }
                            }
                        } else {
                            productDoListFailed.addAll(failedItems);
                        }
                        List<OrderOutputProductAddReq> productAddList2 = new ArrayList<>();
                        //所有捆包仓库无库存的产品
                        if (productDoListFailed.size() > 0) {//捆包仓库无库存，分别发
                            LambdaQueryWrapper<StorageDo> queryWrapper = new LambdaQueryWrapper();
                            queryWrapper.eq(StorageDo::getCountryType, 1);
                            List<StorageDo> storageDoList = storageDao.selectList(queryWrapper);
                            for (OrderShopifyProductDo productDo : productDoListFailed) {
                                storageId = 0L;
                                shipPirce = 99999D;
                                Long productId = getProductId(productDo.getSku(), res.getCompanyId());
                                int count = productDo.getQuantity();
                                if (count < 1) count = productDo.getQuantity();
                                for (StorageDo storageDo : storageDoList) {//遍历仓库是否都有库存
                                    LambdaQueryWrapper<StockRecordDo> wrapper2 = new LambdaQueryWrapper();
                                    size = shipPriceService.countSameSkuSize(new double[4], productId, 1);
                                    wrapper2.eq(StockRecordDo::getShopId, res.getShopId()).eq(StockRecordDo::getProductInfoId, productId).eq(StockRecordDo::getStorageId, storageDo.getId());
                                    StockRecordDo stockRecordDo1 = stockDao.selectOne(wrapper2);
                                    int noDeliveredCount1 = stockDao.getOrderOutCount(productId, res.getShopId(), storageDo.getId()) + stockDao.getOrderOutTurn2FbaCount(productId, res.getShopId(), storageDo.getId());
                                    if (stockRecordDo1 != null && stockRecordDo1.getCanSellCount() - noDeliveredCount1 >= count) {
                                        List<ShipPriceDo> shipPriceDos = shipPriceService.queryByRegionAndSize(res.getPostCode(), size[3], size[0] + size[1] + size[2], size[0], size[1], size[2], res.getCod(), res.getShipmentType(), storageDo.getId(), 1);
                                        if (shipPriceDos.size() < 1 || shipPriceDos.get(0).getPrice() == 0) continue;
                                        if (shipPirce > shipPriceDos.get(0).getPrice()) {//选择最便宜的价格
                                            shipPirce = shipPriceDos.get(0).getPrice();
                                            storageId = storageDo.getId();
                                        }
                                    }
                                }
                                if (storageId != 0) {
                                    OrderOutputProductAddReq productDetail = new OrderOutputProductAddReq();
                                    productAddList2 = new ArrayList<>();
                                    productDetail.setProductId(productId);
                                    productDetail.setCount(count);
                                    productAddList2.add(productDetail);
                                    packageDetail = new OrderOutputPackageAddReq();
                                    packageAddReqList = new ArrayList<>();
                                    packageDetail.setProductList(productAddList2);
                                    addReq = new OrderOutputAddReq();
                                    BeanUtils.copyProperties(res, addReq);
                                    packageAddReqList.add(packageDetail);
                                    addReq.setStorageId(storageId);
                                    addReq.setPackageList(packageAddReqList);
//                                if (orderCount > 0) addReq.setOrderNo(addReq.getOrderNo() + "-" + orderCount);
//                                orderCount++;
                                    orderOutputAddReqList.add(addReq);
                                } else {
                                    //剩余SKU都没有库存
                                    failOrders.add(StringsUtil.createI18Message(SysConstant.OrderYahoo_Stock_NotEnough, OrderShopifyDo.getOrderNumber(), failedItems.get(0).getSku()));
                                }
                            }
                        }
                    }
                }
            }
            if (orderOutputAddReqList.size() > 0) {
                operateRecordDao.operateAddRecord(SysConstant.OPERATE_CLICK_SEND, OrderShopifyDo.getId(), userId, 7);
            }
        }
        for (OrderOutputAddReq outputAddReq : orderOutputAddReqList) {
            StringBuilder sku = new StringBuilder();
            int cout = 0;
            for (OrderOutputProductAddReq orderOutputProductAddReq : outputAddReq.getPackageList().get(0).getProductList()) {
                cout = cout + orderOutputProductAddReq.getCount();
                if (StringUtils.isNotBlank(sku.toString())) {
                    sku.append(",");
                }
                sku.append(productInfoDao.selectById(orderOutputProductAddReq.getProductId()).getCommoditySku());
            }
            outputAddReq.setSku(sku.toString());
            outputAddReq.setCount(cout);
        }
        if (isAuto) {
            sendOutMatch(orderOutputAddReqList, userId, isAuto);
        }

        Map map = new HashMap();
        map.put("orderList", orderOutputAddReqList);
        map.put("failedList", failOrders);
        map.put("storageList", storageDao.selectList(null));
        return SingleResult.success(map);
    }

    @Override
    public SingleResult sendOutNopackage(String id, Long userId, Long companyId) {
        sufficientFundsCheck(companyId);
        List<OrderOutputAddReq> orderOutputAddReqList = new ArrayList<>();
        List<String> failOrders = new ArrayList<>();
        OrderShopifyDo OrderShopifyDo = this.baseMapper.selectById(id);
        if (OrderShopifyDo == null) {
            throw new BizException(SysConstant.Order_NotExist1);
        }
        if ("Canceled".equals(OrderShopifyDo.getFinancialStatus())) {
            throw new BizException(SysConstant.OrderYahoo_Canceled_OrderId, OrderShopifyDo.getOrderName());
        }
        LambdaQueryWrapper<OrderShopifyProductDo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(OrderShopifyProductDo::getOrderId, id);
        List<OrderShopifyProductDo> itemsDoList = productDao.selectList(wrapper);
        //订单
        OrderOutputAddReq res = new OrderOutputAddReq();
        res.setPlatformNumber("shopify");
        res.setPlatformNumber(OrderShopifyDo.getId() + "");
        res.setSendDate(new Date());
        res.setShopId(OrderShopifyDo.getShopId());
        res.setCompanyId(OrderShopifyDo.getCompanyId());
        res.setOrderNo(OrderShopifyDo.getOrderNumber() + "");
        res.setReceiverName(OrderShopifyDo.getShippingName());
        res.setTelPhone(OrderShopifyDo.getShippingPhone());
        res.setPostCode(OrderShopifyDo.getShippingZip());
        res.setArea(OrderShopifyDo.getShippingProvince());
        if (org.apache.commons.lang3.StringUtils.isNotBlank(OrderShopifyDo.getShippingCity())) {
            res.setAddress(OrderShopifyDo.getShippingCity() + OrderShopifyDo.getShippingAddress());
        } else {
            res.setAddress(OrderShopifyDo.getShippingAddress());
        }

        //item
        List<OrderOutputProductAddReq> orderOutputProductDetailList = new ArrayList<>();
        LambdaQueryWrapper<StorageDo> queryWrapper = new LambdaQueryWrapper();
        queryWrapper.eq(StorageDo::getSupportShip, 0);
        List<StorageDo> storageDoList = storageDao.selectList(queryWrapper);
        for (OrderShopifyProductDo productDo : itemsDoList) {
            long storageId = 0L;
            double shipPirce = 99999D;
            int count = productDo.getQuantity();
            if (count < 1) count = productDo.getQuantity();
            Long productId = getProductId(productDo.getSku(), res.getCompanyId());
            for (StorageDo storageDo : storageDoList) {//遍历仓库是否都有库存
                LambdaQueryWrapper<StockRecordDo> wrapper2 = new LambdaQueryWrapper();
                double[] size = shipPriceService.countSameSkuSize(new double[4], productId, 1);
                wrapper2.eq(StockRecordDo::getShopId, res.getShopId()).eq(StockRecordDo::getProductInfoId, productId).eq(StockRecordDo::getStorageId, storageDo.getId());
                StockRecordDo stockRecordDo1 = stockDao.selectOne(wrapper2);
                int noDeliveredCount1 = stockDao.getOrderOutCount(productId, res.getShopId(), storageDo.getId()) + stockDao.getOrderOutTurn2FbaCount(productId, res.getShopId(), storageDo.getId());
                if (stockRecordDo1 != null && stockRecordDo1.getCanSellCount() - noDeliveredCount1 >= count) {
                    List<ShipPriceDo> shipPriceDos = shipPriceService.queryByRegionAndSize(res.getPostCode(), size[3], size[0] + size[1] + size[2], size[0], size[1], size[2], res.getCod(), res.getShipmentType(), storageDo.getId(), 1);
                    if (shipPriceDos.size() < 1 || shipPriceDos.get(0).getPrice() == 0) continue;
                    if (shipPirce > shipPriceDos.get(0).getPrice()) {//选择最便宜的价格
                        shipPirce = shipPriceDos.get(0).getPrice();
                        storageId = storageDo.getId();
                    }
                }
            }
            if (storageId != 0) {
                OrderOutputProductAddReq productDetail = new OrderOutputProductAddReq();
                productDetail.setProductId(productId);
                productDetail.setCount(count);
                List<OrderOutputProductAddReq> productAddList = new ArrayList<>();
                productAddList.add(productDetail);
                OrderOutputPackageAddReq packageDetail = new OrderOutputPackageAddReq();
                List<OrderOutputPackageAddReq> packageAddReqList = new ArrayList<>();
                packageDetail.setProductList(productAddList);
                OrderOutputAddReq addReq = new OrderOutputAddReq();
                BeanUtils.copyProperties(res, addReq);
                packageAddReqList.add(packageDetail);
                if (storageId != 0) {
                    addReq.setStorageId(storageId);
                    addReq.setPackageList(packageAddReqList);
                    orderOutputAddReqList.add(addReq);
                }
            } else {
                //剩余SKU都没有库存
                failOrders.add(StringsUtil.createI18Message(SysConstant.OrderYahoo_Stock_NotEnough, OrderShopifyDo.getOrderName(), productDo.getSku()));
            }

        }

        if (orderOutputAddReqList.size() > 0) {
            operateRecordDao.operateAddRecord(SysConstant.OPERATE_CLICK_SEND, OrderShopifyDo.getId(), userId, 7);
        }
        for (OrderOutputAddReq outputAddReq : orderOutputAddReqList) {
            StringBuilder sku = new StringBuilder();
            int cout = 0;
            for (OrderOutputProductAddReq orderOutputProductAddReq : outputAddReq.getPackageList().get(0).getProductList()) {
                cout = cout + orderOutputProductAddReq.getCount();
                if (org.apache.commons.lang3.StringUtils.isNotBlank(sku)) {
                    sku.append(",");
                }
                sku.append(productInfoDao.selectById(orderOutputProductAddReq.getProductId()).getCommoditySku());
            }
            outputAddReq.setSku(sku.toString());
            outputAddReq.setCount(cout);
        }
        Map map = new HashMap();
        map.put("orderList", orderOutputAddReqList);
        map.put("failedList", failOrders);
        map.put("storageList", storageDao.selectList(null));
        return SingleResult.success(map);
    }

    @Override
    public SingleResult sendOutMatch(List<OrderOutputAddReq> orderOutputAddReqList, Long userId, boolean isAuto) {
        List<String> failOrders = new ArrayList<>();
        failOrders.addAll(outputService.addAmazonList(orderOutputAddReqList, userId));
//        return SingleResult.success(String.format("成功导出%d个发货单", orderOutputAddReqList.size() - failOrders.size()), failOrders);;
        if (failOrders.size() > 0) {
            return SingleResult.failure("300", SysConstant.OrderYahoo_Export_Success, failOrders, orderOutputAddReqList.size() - failOrders.size());
        } else {
            return SingleResult.success(failOrders);
        }
    }

    private void sufficientFundsCheck(Long companyId) {
        if (!companyAccountService.getIsDue(companyId)) {
            throw new NotSufficientFundsException(ErrorEnum.NOT_SUFFICIENT_FUNDS);
        }
    }

    private Long getProductId(String sellerSku, Long companyId) {
        QueryWrapper productWrapper = new QueryWrapper();
        productWrapper.eq("commodity_sku", sellerSku);
        productWrapper.eq("company_id", companyId);
        productWrapper.last("limit 1");
        ProductInfoDo productInfoDo = productInfoDao.selectOne(productWrapper);
        if (productInfoDo == null) {
            QueryWrapper skuWrapper = new QueryWrapper();
            skuWrapper.eq("sub_sku", sellerSku);
            skuWrapper.eq("company_id", companyId);
            skuWrapper.last("limit 1");
            ProductSkuMapDo productSkuMapDo = productSkuMapDao.selectOne(skuWrapper);
            if (productSkuMapDo == null) return null;
            return productSkuMapDo.getProductInfoId();
        } else {
            return productInfoDo.getId();
        }
    }

    private Long getSubProductId(String sellerSku, Long companyId) {
        QueryWrapper skuWrapper = new QueryWrapper();
        skuWrapper.eq("sub_sku", sellerSku);
        skuWrapper.eq("company_id", companyId);
        ProductSkuMapDo productSkuMapDo = productSkuMapDao.selectOne(skuWrapper);
        if (productSkuMapDo == null) return null;
        return productSkuMapDo.getProductInfoId();
    }

    @Override
    public SingleResult pageInit(Long userId, Long companyId) {
        Map result = new HashMap();
        List<Map> shopList = new ArrayList<>();
        UserDo userDo = userDao.selectById(userId);
        if (userDo == null) {
            throw new BizException(SysConstant.User_NotExist);
        }
        QueryWrapper shopWrapper = new QueryWrapper();
        if (userDo.getShopId() != null) shopWrapper.eq("id", userDo.getShopId());
//        shopWrapper.eq("company_id", companyId);
        shopWrapper.eq("platform_id", DicBusinessItemConstant.shopify);
        List<ShopDo> shopDoList = shopDao.selectList(shopWrapper);
        if (!CollectionUtils.isEmpty(shopDoList)) {
            for (ShopDo shopDo : shopDoList) {
                Map shopMap = new HashMap();
                shopMap.put("id", shopDo.getId());
                shopMap.put("value", shopDo.getShopName());
                shopList.add(shopMap);
            }
        }
        result.put("shopList", shopList);
//        result.put("financialStatusList", getFinancialStatusList());
//        result.put("fulfillmentStatusList", getFulfillmentStatusList());

        return SingleResult.success(result);
    }


    @Override
    public ShopifyShippingEneity buildFulfillmentData(OrderOutputDo sendOutEntity) {


        return null;
    }

    /**
     * 上传shopify订单数据
     *
     * @param shopifyOrderMap
     * @author zhujiale
     * @date 2000 03 01
     */
    @Override
    public void dealShopifyOrdersByIds(Map<Long, List<ShopifyRequestReq>> shopifyOrderMap) {
        if (shopifyOrderMap.size() > 0) {
            for (Long key : shopifyOrderMap.keySet()) {
                List<ShopifyRequestReq> list = shopifyOrderMap.get(key);
                Map<Long, List<ShopifyRequestReq>> listMap = new HashMap<>();
                for (ShopifyRequestReq shopifyRequestReq : list) {
                    if (listMap.get(shopifyRequestReq.getOrderId()) == null) {
                        listMap.put(shopifyRequestReq.getOrderId(), new ArrayList<>());
                    }
                    listMap.get(shopifyRequestReq.getOrderId()).add(shopifyRequestReq);
                }
                for (Long orderId : listMap.keySet()) {
                    OrderShopifyDo shopifyDo = dao.selectOne(new QueryWrapper<OrderShopifyDo>().eq("order_id", orderId).eq("shop_id", key));
                    ShopDo shopDo = shopDao.selectById(shopifyDo.getShopId());
                    if (shopDo == null) {
                        throw new BizException(SysConstant.Shop_NotExist);
                    }
                    List<ShopifyRequestReq> shopifyRequests = listMap.get(orderId);
                    List<OrderFulfillmentOrderEntity> fulfillmentOrders = getFulfillmentOrders(shopDo, orderId);

                    if (fulfillmentOrders.size() < 1) {

                    } else if (fulfillmentOrders.size() == 1 && fulfillmentOrders.get(0).getLineItems().size() == 1 && shopifyRequests.size() == 1) {
                        //一个order只有一个fulfillment且只有一个出库订单
                        dpPostOrderFulfillmentsSingle(shopDo, shopifyRequests.get(0), shopifyDo, fulfillmentOrders.get(0), true);
                    } else {
                        dpPostOrderFulfillmentsMulti(shopDo, shopifyRequests, shopifyDo, fulfillmentOrders);
                    }
                    //判断收款信息，并收款
                    if (shopifyDo.getFinancialStatus().equals("authorized") || shopifyDo.getFinancialStatus().equals("pending")) {
                        try {
                            getOrderTransactions(shopDo, orderId);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    }

    /**
     * 多fulfullmentId上传单号
     *
     * @param shopDo
     * @param shopifyRequests
     * @param shopifyDo
     * @param fulfillmentOrders
     */
    private void dpPostOrderFulfillmentsMulti(ShopDo shopDo, List<ShopifyRequestReq> shopifyRequests, OrderShopifyDo shopifyDo,
                                              List<OrderFulfillmentOrderEntity> fulfillmentOrders) {
//        if (shopifyRequests.size() == fulfillmentOrders.size()) {
        //发货数量和订单数量一致的情况，全部发货
        for (int i = 0; i < shopifyRequests.size(); i++) {
            ShopifyRequestReq shopifyRequest = shopifyRequests.get(i);
            Long orderOutputId = shopifyRequests.get(i).getOrderOutputId();
            Long packageDetailId = shopifyRequests.get(i).getPackageDetailId();
            OrderOutputPackageDetailDo orderPackageDetailDo = packageDetailDao.selectById(packageDetailId);
            String[] split = orderPackageDetailDo.getInSkuId().split(",");
            if (split == null || split.length < 1) {
                break;
            }
            int total = fulfillmentOrders.get(0).getLineItems().stream().mapToInt(OrderFulfillmentOrderEntity.LineItemsDTO::getFulfillableQuantity).sum();
            if (fulfillmentOrders.size() == 1 && total == split.length) {
                dpPostOrderFulfillmentsSingle(shopDo, shopifyRequest, shopifyDo, fulfillmentOrders.get(0), true);
            }
            Map<String, Integer> stringIntegerMap = Arrays.stream(split).collect(Collectors.toMap(s -> s, s -> 1, Integer::sum));
            for (String skuId : stringIntegerMap.keySet()) {
                if (StringUtils.isNotBlank(skuId)) {
                    kk:
                    for (OrderFulfillmentOrderEntity fulfillmentOrderEntity : fulfillmentOrders) {
                        for (OrderFulfillmentOrderEntity.LineItemsDTO lineItem : fulfillmentOrderEntity.getLineItems()) {

                            ProductInfoDo productInfoDo = productInfoDao.selectById(skuId);
                            List<ProductSkuMapDo> productInfSkuMapDoList = productSkuMapDao.selectList(
                                    new LambdaQueryWrapper<ProductSkuMapDo>().eq(ProductSkuMapDo::getProductInfoId, skuId));
                            List<String> stringList = new ArrayList<>();
                            if (productInfSkuMapDoList != null && productInfSkuMapDoList.size() > 0)
                                stringList = productInfSkuMapDoList.stream().map(ProductSkuMapDo::getSubSku).collect(Collectors.toList());
                            LambdaQueryWrapper<OrderShopifyProductDo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                            lambdaQueryWrapper.eq(OrderShopifyProductDo::getItemId, lineItem.getLineItemId());
                            OrderShopifyProductDo productInfoDo1 = orderShopifyProductDao.selectOne(lambdaQueryWrapper);
                            if (productInfoDo != null && productInfoDo1 != null) {
                                if (productInfoDo1.getSku().contains(productInfoDo.getCommoditySku()) ||
                                        productInfoDo.getCommoditySku().equals(productInfoDo1.getSku())
                                        || stringList.contains(productInfoDo1.getSku())) {

                                    dpPostOrderFulfillmentsSingle(shopDo, shopifyRequest, shopifyDo, fulfillmentOrderEntity, false);
                                    continue kk;
                                } else if (productInfoDo1.getSku().contains("\\+")) {
                                    if (productInfoDo1.getSku().contains(productInfoDo.getCommoditySku())) {
                                        dpPostOrderFulfillmentsSingle(shopDo, shopifyRequest, shopifyDo, fulfillmentOrderEntity, false);
                                        continue kk;
                                    } else {
                                        for (String s : productInfoDo1.getSku().split("\\+")) {
                                            if (stringList.contains(s)) {
                                                dpPostOrderFulfillmentsSingle(shopDo, shopifyRequest, shopifyDo, fulfillmentOrderEntity, false);
                                                continue kk;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

        }
    }
//                List<OrderOutputProductDo> productDoList = orderOutputProductDao.selectList(new QueryWrapper<OrderOutputProductDo>().eq("order_id", orderOutputId));
//                int sum = productDoList.stream().mapToInt(OrderOutputProductDo::getCount).sum();
//        if (productDoList.size() == fulfillmentOrders.get(i).getLineItems().size() ||
//                sum == total) {
//                dpPostOrderFulfillmentsSingle(shopDo, shopifyRequest, shopifyDo, fulfillmentOrders.get(i), true);
//        } else if (productDoList.size() > fulfillmentOrders.get(i).getLineItems().size()) {
//            dpPostOrderFulfillmentsSingle(shopDo, shopifyRequest, shopifyDo, fulfillmentOrders.get(i), false);
//        } else if (productDoList.size() < fulfillmentOrders.get(i).getLineItems().size()) {
//            dpPostOrderFulfillmentsSingle(shopDo, shopifyRequest, shopifyDo, fulfillmentOrders.get(i), false);
//        }
//    }
//        } else if (shopifyRequests.size() > fulfillmentOrders.size()) {
//            //发货数量大于订单数量，拆单发货
////            for (int i = 0; i < shopifyRequests.size(); i++) {
////                OrderFulfillmentOrderEntity fulfillmentOrder;
////                ShopifyRequestReq shopifyRequest = shopifyRequests.get(i);
////                if (fulfillmentOrders.size() >= i)
////                    fulfillmentOrder = fulfillmentOrders.get(fulfillmentOrders.size() - 1);
////                else
////                    fulfillmentOrder = fulfillmentOrders.get(i);
////                dpPostOrderFulfillmentsSingle(shopDo, shopifyRequest, shopifyDo, fulfillmentOrder, i == shopifyRequests.size() - 1);
////            }
//            for (int i = 0; i < shopifyRequests.size(); i++) {
//                OrderFulfillmentOrderEntity fulfillmentOrder = null;
//                if (fulfillmentOrders.size() <= i)
//                    fulfillmentOrder = fulfillmentOrders.get(fulfillmentOrders.size() - 1);
//                else fulfillmentOrder = fulfillmentOrders.get(i);
//                dpPostOrderFulfillmentsSingle(shopDo, shopifyRequests.get(i), shopifyDo, fulfillmentOrder, false);
//            }
//        } else if (shopifyRequests.size() < fulfillmentOrders.size()) {
//            //发货数量小于订单数量，最后一单并单发货
//            for (int i = 0; i < fulfillmentOrders.size(); i++) {
//                ShopifyRequestReq shopifyRequest = null;
//                if (shopifyRequests.size() <= i)
//                    shopifyRequest = shopifyRequests.get(shopifyRequests.size() - 1);
//                else
//                    shopifyRequest = shopifyRequests.get(i);
//                dpPostOrderFulfillmentsSingle(shopDo, shopifyRequest, shopifyDo, fulfillmentOrders.get(i), false);
//            }
//        }
//    }

    /**
     * 单fulfullmentId上传单号
     *
     * @param shopDo
     * @param shopifyRequestReq
     * @param shopifyDo
     * @param orderFulfillmentOrderEntity
     * @param b                           是否发完整个fulfillment——order产品
     */
    private void dpPostOrderFulfillmentsSingle(ShopDo shopDo, ShopifyRequestReq shopifyRequestReq, OrderShopifyDo shopifyDo, OrderFulfillmentOrderEntity orderFulfillmentOrderEntity, boolean b) {
        List<OrderShopifyShipDo> shopifyShipDoList = orderShopifyShipDao.selectList(new LambdaQueryWrapper<OrderShopifyShipDo>().eq(OrderShopifyShipDo::getOrderId, shopifyDo.getOrderId()).eq(OrderShopifyShipDo::getFulfillmentOrderId, orderFulfillmentOrderEntity.getId()));
        //判断shopify订单数据是否上传过 上传过了更新 没上传过插入
        if (shopifyShipDoList.size() > 0 && (!orderFulfillmentOrderEntity.getStatus().equals("open") && !orderFulfillmentOrderEntity.getStatus().equals("in_progress"))) {
            doUpdateTrackNumber(shopifyShipDoList, shopDo, shopifyDo, shopifyRequestReq);
        } else {
            String addUrl = "https://" + shopDo.getShopifyHost() + "/admin/api/2023-07/fulfillments.json";
            Map paraMap = new HashMap();
            AddFulfillmentReqParams fulfillmentReqParams = new AddFulfillmentReqParams();
            AddFulfillmentReqParams.TrackingInfoDTO trackingInfoDTO = new AddFulfillmentReqParams.TrackingInfoDTO();
            AddFulfillmentReqParams.LineItemsByFulfillmentOrderDTO itemsByFulfillmentOrderDTO = new AddFulfillmentReqParams.LineItemsByFulfillmentOrderDTO();
            List<AddFulfillmentReqParams.LineItemsByFulfillmentOrderDTO> fulfillmentOrderDTOList = new ArrayList<>();
            paraMap.put("fulfillment", fulfillmentReqParams);
            fulfillmentReqParams.setNotifyCustomer(true);
            trackingInfoDTO.setCompany(shopifyRequestReq.getCompany());
            trackingInfoDTO.setUrl(shopifyRequestReq.getUrl());
            trackingInfoDTO.setNumber(shopifyRequestReq.getNumber());
            itemsByFulfillmentOrderDTO.setFulfillmentOrderId(orderFulfillmentOrderEntity.getId());
            if (b)
                itemsByFulfillmentOrderDTO.setFulfillmentOrderLineItems(buildFulfillmentOrderLineItems(orderFulfillmentOrderEntity.getLineItems()));
            else
                itemsByFulfillmentOrderDTO.setFulfillmentOrderLineItems(buildFulfillmentOrderLineItems(orderFulfillmentOrderEntity.getLineItems(),
                        shopifyRequestReq.getOrderOutputId(), shopifyRequestReq.getPackageDetailId()));
            fulfillmentOrderDTOList.add(itemsByFulfillmentOrderDTO);
            fulfillmentReqParams.setLineItemsByFulfillmentOrder(fulfillmentOrderDTOList);
            fulfillmentReqParams.setTrackingInfo(trackingInfoDTO);
            //调用成功后讲数据保存至t_order_shopify_ship表中
            logger.info("新增shopify_fulfillments订单数据调用接口时参数：" + JSON.toJSONString(paraMap));
            String s = httpPost(addUrl, shopDo, JSON.toJSONString(paraMap));
            try {
                logger.info("新增shopify_fulfillments订单数据返回：" + s);
                JSONObject jsonObject = JSON.parseObject(s);
                if (jsonObject.getJSONObject("fulfillment") != null) {
                    JSONObject jb = jsonObject.getJSONObject("fulfillment");
                    OrderShopifyShipDo addResultDo = buildShippingUpdateEntity(jb, orderFulfillmentOrderEntity.getId());
                    addResultDo.setCreatedAt(jb.getDate("create_at"));
                    orderShopifyShipDao.insert(addResultDo);
                    dao.updateOrderUploadExpress(shopifyDo.getId());
                    operateRecordDao.operateAddRecord(SysConstant.OPERATE_UPLOAD_TRACK, shopifyDo.getId(), 1L, 7);
                } else if (jsonObject.getString("errors") != null) {
                    logger.error(jsonObject.toJSONString());
                } else if (jsonObject.getJSONObject("errors") != null) {
                    JSONObject errors = jsonObject.getJSONObject("errors");
                    JSONArray base = errors.getJSONArray("base");
                    String string = base.getString(0);
                    if (string != null && string.contains("already fulfilled")) {
                        //                    doUpdateTrackNumber(shopifyShipDoList, shopDo, shopifyDo, shopifyRequestReq);
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
                logger.error(e.getLocalizedMessage());
            }
        }
    }

    private List<AddFulfillmentReqParams.LineItemsByFulfillmentOrderDTO.FulfillmentOrderLineItemsDTO>
    buildFulfillmentOrderLineItems(List<OrderFulfillmentOrderEntity.LineItemsDTO> lineItems, Long orderOutputId, Long packageDetailId) {
        OrderOutputPackageDetailDo orderPackageDetailDo = packageDetailDao.selectById(packageDetailId);
        List<AddFulfillmentReqParams.LineItemsByFulfillmentOrderDTO.FulfillmentOrderLineItemsDTO> itemsDTOList = new ArrayList<>();
        if (orderPackageDetailDo == null) {
            List<OrderOutputProductDo> productDoList = orderOutputProductDao.selectList(new QueryWrapper<OrderOutputProductDo>().eq("order_id", orderOutputId));
            if (productDoList == null) {
                return new ArrayList<>();
            }
            for (OrderOutputProductDo productDo : productDoList) {
                for (OrderFulfillmentOrderEntity.LineItemsDTO lineItem : lineItems) {
                    ProductInfoDo productInfoDo = productInfoDao.selectById(productDo.getProductId());
                    List<ProductSkuMapDo> productInfSkuMapDoList = productSkuMapDao.selectList(
                            new LambdaQueryWrapper<ProductSkuMapDo>().eq(ProductSkuMapDo::getProductInfoId, productDo.getProductId()));
                    List<String> stringList = new ArrayList<>();
                    if (productInfSkuMapDoList != null && productInfSkuMapDoList.size() > 0)
                        stringList = productInfSkuMapDoList.stream().map(ProductSkuMapDo::getSubSku).collect(Collectors.toList());
                    LambdaQueryWrapper<OrderShopifyProductDo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                    lambdaQueryWrapper.eq(OrderShopifyProductDo::getItemId, lineItem.getLineItemId());
                    OrderShopifyProductDo productInfoDo1 = orderShopifyProductDao.selectOne(lambdaQueryWrapper);
                    if (productInfoDo != null && productInfoDo1 != null) {
                        if (productInfoDo.getCommoditySku().equals(productInfoDo1.getSku()) || stringList.contains(productInfoDo1.getSku())) {
                            AddFulfillmentReqParams.LineItemsByFulfillmentOrderDTO.FulfillmentOrderLineItemsDTO itemsDTO = new AddFulfillmentReqParams.LineItemsByFulfillmentOrderDTO.FulfillmentOrderLineItemsDTO();
                            itemsDTO.setId(lineItem.getId());
                            if (lineItem.getFulfillableQuantity() < 1)
                                continue;
                            itemsDTO.setQuantity(lineItem.getFulfillableQuantity());
                            itemsDTOList.add(itemsDTO);
                        }
                    }
                }
            }
        } else {
            for (OrderFulfillmentOrderEntity.LineItemsDTO lineItem : lineItems) {
                String[] split = orderPackageDetailDo.getInSkuId().split(",");
                if (split == null || split.length < 1) {
                    break;
                }
                Map<String, Integer> stringIntegerMap = Arrays.stream(split).collect(Collectors.toMap(s -> s, s -> 1, Integer::sum));
                for (String skuId : stringIntegerMap.keySet()) {
                    if (StringUtils.isNotBlank(skuId)) {
                        int count = stringIntegerMap.get(skuId);
                        LambdaQueryWrapper<OrderShopifyProductDo> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                        lambdaQueryWrapper.eq(OrderShopifyProductDo::getItemId, lineItem.getLineItemId());
                        OrderShopifyProductDo productInfoDo1 = orderShopifyProductDao.selectOne(lambdaQueryWrapper);
                        ProductInfoDo productInfoDo = productInfoDao.selectById(skuId);
                        if (productInfoDo == null) continue;
                        List<ProductSkuMapDo> productSkuMapDos = productSkuMapDao.selectList(new LambdaQueryWrapper<ProductSkuMapDo>().eq(ProductSkuMapDo::getProductInfoId, skuId));
                        List<String> collect = new ArrayList<>();
                        if (productSkuMapDos != null) {
                            collect = productSkuMapDos.stream().map(ProductSkuMapDo::getSubSku).collect(Collectors.toList());
                            if (productInfoDo != null && productInfoDo1 != null) {
                                if (productInfoDo.getCommoditySku().equals(productInfoDo1.getSku())
                                        || collect.contains(productInfoDo1.getSku())) {
                                    AddFulfillmentReqParams.LineItemsByFulfillmentOrderDTO.FulfillmentOrderLineItemsDTO itemsDTO = new AddFulfillmentReqParams.LineItemsByFulfillmentOrderDTO.FulfillmentOrderLineItemsDTO();
                                    itemsDTO.setId(lineItem.getId());
                                    if (lineItem.getFulfillableQuantity() < 1)
                                        continue;
                                    itemsDTO.setQuantity(count);
                                    itemsDTOList.add(itemsDTO);
                                }
                            }
                        }
                    }
                }
            }
        }
        return itemsDTOList;
    }

    private List<AddFulfillmentReqParams.LineItemsByFulfillmentOrderDTO.FulfillmentOrderLineItemsDTO> buildFulfillmentOrderLineItems
            (List<OrderFulfillmentOrderEntity.LineItemsDTO> lineItems) {
        List<AddFulfillmentReqParams.LineItemsByFulfillmentOrderDTO.FulfillmentOrderLineItemsDTO> itemsDTOList = new ArrayList<>();
        for (OrderFulfillmentOrderEntity.LineItemsDTO lineItem : lineItems) {
            AddFulfillmentReqParams.LineItemsByFulfillmentOrderDTO.FulfillmentOrderLineItemsDTO itemsDTO = new AddFulfillmentReqParams.LineItemsByFulfillmentOrderDTO.FulfillmentOrderLineItemsDTO();
            itemsDTO.setId(lineItem.getId());
            itemsDTO.setQuantity(lineItem.getFulfillableQuantity());
            itemsDTOList.add(itemsDTO);
        }
        return itemsDTOList;
    }

    private void updateLocationInfo(ShopDo shopDo) {
        String addUrl = "https://" + shopDo.getShopifyHost() + "/admin/api/2023-07/locations.json";
        String s = httpGet(addUrl, shopDo);
        JSONObject jsonObject = JSON.parseObject(s);
        List<OrderShopifyLocationEntity> locations = JSON.parseArray(jsonObject.getString("locations"), OrderShopifyLocationEntity.class);
        for (OrderShopifyLocationEntity location : locations) {
            if (location.getActive()) {
                long locationId = location.getId();
                redisTemplate.opsForValue().set(SHOPIFY_LOCATION + shopDo.getId(), locationId);
            }
        }

    }

    private void doUpdateTrackNumber(List<OrderShopifyShipDo> shopifyShipDoList, ShopDo
            shopDo, OrderShopifyDo
                                             shopifyDo, ShopifyRequestReq shopifyRequest) {
        OrderShopifyShipDo shopifyShipDo = shopifyShipDoList.get(0);
        //修改订单时，只有原出库单对应的shipping表匹配时才可以更新
        String updateUrl = "https://" + shopDo.getShopifyHost() + "/admin/api/2023-07/orders/" + shopifyDo.getOrderId() + "/fulfillments/" + shopifyShipDo.getFulfillmentId() + ".json";
        //组装接口请求体
        UpdateShopifyRequestReq updateRequest = new UpdateShopifyRequestReq();
        UpdateFulfillmentParams updateParams = new UpdateFulfillmentParams();
        updateParams.setId(shopifyShipDo.getFulfillmentId());
        updateParams.setTracking_number(shopifyRequest.getNumber());
        updateParams.setTracking_company(shopifyRequest.getCompany());
        updateRequest.setFulfillment(updateParams);
        logger.debug("修改shopify_fulfillments订单数据调用接口时参数：" + JSON.toJSONString(updateRequest));
        String s = httpPut(updateUrl, shopDo, JSON.toJSONString(updateRequest));
        logger.info("修改shopify订单数据" + s);

        JSONObject jsonObject = JSON.parseObject(s);
        //调用成功后讲数据保存至t_order_shopify_ship表中
        if (jsonObject.getJSONObject("fulfillment") != null) {
            JSONObject jb = jsonObject.getJSONObject("fulfillment");
            OrderShopifyShipDo updateResultDo = buildShippingUpdateEntity(jb, null);
            updateResultDo.setId(shopifyShipDo.getId());
            updateResultDo.setUpdatedAt(jb.getDate("update_at"));
            orderShopifyShipDao.updateById(updateResultDo);
        }
    }

    private OrderShopifyShipDo buildShippingUpdateEntity(JSONObject jb, Long fulfillmentOrderId) {
        OrderShopifyShipDo updateResultDo = new OrderShopifyShipDo();
        updateResultDo.setFulfillmentId(jb.getLong("id"));
        updateResultDo.setFulfillmentOrderId(fulfillmentOrderId);
        updateResultDo.setLocationId(jb.getLong("location_id"));
        updateResultDo.setOrderId(jb.getLong("order_id"));
        updateResultDo.setStatus(jb.getString("status"));
        updateResultDo.setShipmentStatus(jb.getString("shipment_status"));
        updateResultDo.setTrackingCompany(jb.getString("tracking_company"));
        updateResultDo.setTrackingNumber(jb.getString("tracking_number"));
        return updateResultDo;
    }

    private void getOrderTransactions(ShopDo shopDo, Long orderId) {
        String addUrl = "https://" + shopDo.getShopifyHost() + "/admin/api/2023-07/orders/" + orderId + "/transactions.json";
        String s = httpGet(addUrl, shopDo);
        JSONObject jsonObject = JSON.parseObject(s);
        List<OrderTransactionEntity> data = JSON.parseArray(jsonObject.getString("transactions"), OrderTransactionEntity.class);
        if (data == null) return;
        for (OrderTransactionEntity transactionEntity : data) {
            if (transactionEntity.getKind().equals("capture") || transactionEntity.getKind().equals("sale")) {
                break;
            }
        }
        for (OrderTransactionEntity transactionEntity : data) {
            if (transactionEntity.getKind().equals("authorization")) {
                //TODO 收款
                dpOrderTransactions(shopDo, orderId, "capture", transactionEntity.getAuthorization());
            }
        }
    }

    private void dpOrderTransactions(ShopDo shopDo, Long orderId, String kind, String authKey) {
        String addUrl = "https://" + shopDo.getShopifyHost() + "/admin/api/2023-07/orders/" + orderId + "/transactions.json";
        Map requestMap = new HashMap();
        Map dataMap = new HashMap();
        dataMap.put("kind", kind);
        dataMap.put("authorization", kind);
        requestMap.put("transaction", dataMap);
        String s = httpPost(addUrl, shopDo, JSON.toJSONString(requestMap));
        logger.info("Shopify收款接口" + s);
        OrderTransactionEntity data = JSON.parseObject(s, OrderTransactionEntity.class);
    }


    private List<OrderFulfillmentOrderEntity> getFulfillmentOrders(ShopDo shopDo, Long orderId) {
        String addUrl = "https://" + shopDo.getShopifyHost() + "/admin/api/2023-07/orders/" + orderId + "/fulfillment_orders.json";
        String s = httpGet(addUrl, shopDo);
        logger.info("getFulfillmentOrders" + s);
        JSONObject jsonObject = JSON.parseObject(s);
        JSONArray fulfillment_orders = jsonObject.getJSONArray("fulfillment_orders");
        List<OrderFulfillmentOrderEntity> data = JSON.parseArray(fulfillment_orders.toJSONString(), OrderFulfillmentOrderEntity.class);
        if (data == null) {
            return new ArrayList<>();
        }
        return data.stream().filter(orderFulfillmentOrderEntity -> !orderFulfillmentOrderEntity.getStatus().equals("closed")).collect(Collectors.toList());
//        return data;
    }

    private String getOrderShipTypeStr(String orderType) {
//        if ("shipped".equals(orderType) || "fulfilled".equals(orderType)) {
//            return "已发货";
//        } else if ("partial".equals(orderType)) {
//            return "部分发货";
//        } else if ("unshipped".equals(orderType) || orderType == null) {
//            return "未发货";
//        } else if ("restocked".equals(orderType)) {
//            return "取消发货";
//        }
        if (StringUtils.isBlank(orderType)) {
            return StringsUtil.createI18Message("未发货");
        } else {
            return StringsUtil.createI18Message(orderType);
        }
    }

    private String getOrderStatusStr(String orderStatus) {
        return StringsUtil.createI18Message(orderStatus);
    }

    @Override
    public List<OrderShopifyRes> getList(Map<String, String> map) {
        QueryWrapper<OrderShopifyDo> wrapper = queryBuild(map);
        List<OrderShopifyDo> list = this.list(wrapper);
        List<OrderShopifyRes> result = handlerListAfter(list);
        return result;
    }

    @Override
    public PageResult getListPage(Map<String, String> map) {
        QueryWrapper<OrderShopifyDo> wrapper = queryBuild(map);
        IPage<OrderShopifyDo> page = pageInit(map);
        page = this.page(page, wrapper);
        List<OrderShopifyRes> resList = handlerListAfter(page.getRecords());
        PageResult result = new PageResult(resList, (int) page.getCurrent(), (int) page.getSize(), (int) page.getTotal(), (int) page.getPages());
        return result;
    }

    //查询分页列表之后对列表数据的处理
    private List<OrderShopifyRes> handlerListAfter(List<OrderShopifyDo> list) {
        List<OrderShopifyRes> result = new ArrayList<>();
        list.forEach(et -> {
            OrderShopifyRes res = new OrderShopifyRes();
            ShopDo shopDo = shopDao.selectById(et.getShopId());
            BeanUtils.copyProperties(et, res);
            res.setFulfillmentStatus(getOrderShipTypeStr(et.getFulfillmentStatus()));
            res.setShippingAddress(res.getShippingCity() + res.getShippingAddress());
            res.setFinancialStatus(getOrderStatusStr(et.getFinancialStatus()));
            if (shopDo != null) res.setShopName(shopDo.getShopName());
            List<OrderShopifyProductDo> shopifyProductDos = orderShopifyProductDao.selectList(new LambdaQueryWrapper<OrderShopifyProductDo>().eq(OrderShopifyProductDo::getOrderId, et.getId()));
            if (shopifyProductDos.size() > 0) {
                List<String> skuList = shopifyProductDos.stream().map(shopifyProductDo -> {
                    return shopifyProductDo.getSku() + "*" + shopifyProductDo.getQuantity();
                }).collect(Collectors.toList());
                String sku = StringUtils.join(skuList, ",");
                res.setSku(sku);
                result.add(res);
            }
        });
        return result;
    }

    @Override
    public SingleResult webhook(String type) {

        return null;
    }

    @Override
    public void autoRefreshOrder() {
        List<ShopDo> shopBeans = shopDao.selectList(null);
        for (ShopDo shop : shopBeans) {
            if (shop.getShopifyHost() != null && shop.getShopifyToken() != null) {
                try {
                    sync(shop.getId(), TimeUtils.getCurrentDateFormat(-3), null);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private IPage<OrderShopifyDo> pageInit(Map<String, String> map) {
        IPage<OrderShopifyDo> page = new Page();
        page.setSize(StringUtils.isNotBlank(map.get("pageSize")) ? Long.parseLong(map.get("pageSize")) : 10);
        page.setCurrent(StringUtils.isNotBlank(map.get("current")) ? Long.parseLong(map.get("current")) : 1);
        return page;
    }

    private QueryWrapper<OrderShopifyDo> queryBuild(Map<String, String> map) {
        QueryWrapper<OrderShopifyDo> wrapper = new QueryWrapper<>();
        if (StringUtils.isNotBlank(map.get("keyword"))) {
            wrapper.like("order_number", map.get("keyword")).or().like("shipping_name", map.get("keyword"));
        }
        if (StringUtils.isNotBlank(map.get("payState"))) {
            wrapper.eq("financial_status", map.get("payState"));
        }
        if (StringUtils.isNotBlank(map.get("shopId"))) {
            wrapper.eq("shop_id", map.get("shopId"));
        }
        if (StringUtils.isNotBlank(map.get("companyId"))) {
            wrapper.eq("company_id", map.get("companyId"));
        }
        if (StringUtils.isNotBlank(map.get("sendState"))) {
            wrapper.eq("fulfillment_status", map.get("sendState"));
        }
        if (StringUtils.isNotBlank(map.get("isSendOut"))) {
            wrapper.eq("is_send_out", map.get("isSendOut"));
        }
        if (StringUtils.isNotBlank(map.get("endDate"))) {
            wrapper.lt("created_at", TimeUtils.addDaysFormat(map.get("endDate"), "yyyy-MM-dd", 1));
        }
        if (StringUtils.isNotBlank(map.get("startDate"))) {
            wrapper.ge("created_at", map.get("startDate"));
        }
        wrapper.orderByDesc("number");
        return wrapper;
    }


}
